package com.szrt.spring.ch03.ioc;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

public class ScottClassPathXmlApplicationContext implements ScottApplicationContext {
	
	/**
	 * 在一个配置文件中可以配置多个<bean>标签
	 */
	private List<Bean> beans = new ArrayList<Bean>();
	
	private Map<String, Object> maps = new HashMap<String, Object>();
	
	public ScottClassPathXmlApplicationContext(String configLocation){
		
		dom4jReadXML(configLocation);
		
		createObject();
		
	}

	/**
	 * 读取到配置文件之后 利用反射实例化具体的对象
	 */
	private void createObject() {
		
		for(Bean bean :beans){
			
			try {
				
				if(null !=bean.getClazz()  && !"".equals(bean.getClazz())){
					//根据字符串实例化具体的对象
					Class<?> clazz = Class.forName(bean.getClazz());
					Object object = clazz.newInstance();
					maps.put(bean.getId(), object);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		
		
		
	}

	/**
	 * 利用dom4j读取配置文件 applicationContext03.xml
	 * @param configLocation
	 */
	@SuppressWarnings("unchecked")
	private void dom4jReadXML(String configLocation) {
		
		//创建1个xml文件读取器
		SAXReader reader  = new SAXReader();
		
		Document document = null;
		
		try {
			
			//得到xml文件
			URL xmlPath = this.getClass().getClassLoader().getResource(configLocation);
			document = reader.read(xmlPath);
			
			Map<String, String> namespace = new HashMap<String, String>();
			
			namespace.put("xmlns", "http://www.springframework.org/schema/beans");
			
			//创建beans/bean查询路径
			XPath createXPath = document.createXPath("//xmlns:beans/xmlns:bean");
			
			//设置命名空间
			createXPath.setNamespaceURIs(namespace);
			
			//获取文档下所有的bean节点
			List<Element> beanList =createXPath.selectNodes(document);
			
			for(Element element :beanList){
				//获取id属性的值
				String id = element.attributeValue("id");
				
				//获取class属性的值
				String clazz = element.attributeValue("class");
				
				Bean bean = new Bean();
				bean.setId(id);
				bean.setClazz(clazz);
				//加入到beans中
				beans.add(bean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	

	@Override
	public Object getBean(String name) {
		return maps.get(name);
	}

}
